 

//package fr.inrialpes.exmo.align.service;
 
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Properties;
import java.io.PrintStream;
import java.io.File;


 
import java.io.FileReader;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;

import java.util.Locale;
import java.util.TimeZone;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.URLEncoder;
import java.net.URLDecoder;

import java.lang.Integer;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.ServletResponseWrapper;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
//import javax.servlet.http.ParameterServletResponseWrapper;

import org.mortbay.jetty.Handler;
import org.mortbay.jetty.handler.AbstractHandler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.Request;
import org.mortbay.servlet.MultiPartFilter;

//import java.lang.reflect.InvocationTargetException;
 

import javax.xml.parsers.*; 
import org.w3c.dom.*; 
import org.xml.sax.*; 
import java.io.*; 

import edu.mit.csail.sdg.alloy4compiler.translator.A4Solution;


public class PlanbycoServer {

	
	public static String CHEMINHTML = "html/";//"bin/";//"";
	public static String CHEMINXML = "xml/";//"bin/";//"";
	public static String CHEMINALS = "als/";// "src/";//"";
        public static String CHEMINLIB = "lib/";
        public static String ALLOYRESULTAT = "alloyResultat.xml";
        public static String ALLOYALS="edt-un-compose.als";
        public static String EDTHTML="edt.html";
	
	
	
    public String //DBMS Parameters
	DBHOST = "localhost",
	DBPORT = "3306",
	DBUSER = "adminAServ",
	DBPASS = "aaa345",
	DBBASE = "AServDB",
	DBMS   = "mysql";

    public static final String //Port Strings
	HTML = "8089",
	JADE = "8888",
	WSDL = "7777",
	JXTA = "6666",
	HTTP_OK = "200 OK",
	HTTP_REDIRECT = "301 Moved Permanently",
	HTTP_FORBIDDEN = "403 Forbidden",
	HTTP_NOTFOUND = "404 Not Found",
	HTTP_BADREQUEST = "400 Bad Request",
	HTTP_INTERNALERROR = "500 Internal Server Error",
	HTTP_NOTIMPLEMENTED = "501 Not Implemented";

    public static final String //IP Strings
	HOST = "localhost";

 public static final String
	MIME_PLAINTEXT = "text/plain",
	MIME_HTML = "text/html",
	MIME_XML = "text/xml",
	MIME_JSON = "application/json",
	MIME_DEFAULT_BINARY = "application/octet-stream";

    public static final int MAX_FILE_SIZE = 10000;

    public static final String HEADER = "<style type=\"text/css\">body { font-family: sans-serif } button {background-color: #DDEEFF; margin-left: 1%; border: #CCC 1px solid;}</style>";


private EmploiDuTemps emploiDuTemps = new EmploiDuTemps();


    private int debug = 0;
    private String filename = null;
    private String outfile = null;
    private String paramfile = null;
 
    private int tcpPort;
    private String tcpHost;
 
    private Server server;
	//ajouter des variable pour tester
	String txt="",ts="";
	String donnees;
   
    public static void main(String[] args) {
	try { new PlanbycoServer().run( args ); }
	catch ( Exception ex ) { ex.printStackTrace(); };
    }
    
    public void run(String[] args) throws Exception {
	 
	tcpPort =  8080;
	tcpHost = HOST;
	server = new Server(tcpPort);

	// The handler deals with the request
	// most of its work is to deal with large content sent in specific ways 
	Handler handler = new AbstractHandler(){
		public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch ) throws IOException, ServletException {
		    String method = request.getMethod();
		    String uri;
		    String parametres = request.getParameter("p0");
		    System.out.println("PlanByCoServer : parametres : "+parametres);
		    //uri = URLDecoder.decode( request.getURI(), "iso-8859-1" );
		    uri = request.getPathInfo();
			donnees=request.getQueryString();
		    Properties header = new Properties();
		    Properties params = new Properties();
		    Enumeration headerNames = request.getHeaderNames();
		    while( headerNames.hasMoreElements() ) {
			String headerName = (String)headerNames.nextElement();
			header.setProperty( headerName, request.getHeader(headerName) );
		    }

		    // Get the content if any
		    // This is supposed to be only an uploaded file
		    // We use jetty MultiPartFilter to decode this file.
		    // Note that this could be made more uniform 
		    // with the text/xml part stored in a file as well.
		    String mimetype = request.getContentType();
		    if ( mimetype != null && mimetype.startsWith("text/xml") ) {
			// Most likely Web service request (REST through POST)
			int length = request.getContentLength();
			if ( length > 0 ) {
			    char [] mess = new char[length+1];
			    try {
				new BufferedReader(new InputStreamReader(request.getInputStream())).read( mess, 0, length);
			    } catch (Exception e) {
				e.printStackTrace(); // To clean up
			    }
			    params.setProperty( "content", new String( mess ) );
			}
		    // File attached to SOAP messages
		    } else if ( mimetype != null && mimetype.startsWith("application/octet-stream") ) {
         		File alignFile = new File(File.separator + "tmp" + File.separator + "XXX.rdf");
         		// check if file already exists - and overwrite if necessary.
         		if (alignFile.exists()) alignFile.delete();
               	 	FileOutputStream fos = new FileOutputStream(alignFile);
            		InputStream is = request.getInputStream();
			
           	        try {
			    byte[] buffer = new byte[4096];
			    int bytes=0; 
			    while (true) {
				bytes = is.read(buffer);
				if (bytes < 0) break;
				fos.write(buffer, 0, bytes);
			    }
            		} catch (Exception e) {
			} finally {
			    fos.flush();
			    fos.close();
			}
               		is.close();
			params.setProperty( "content", "" );
			params.setProperty( "filename" ,  alignFile.getAbsolutePath()  );
         	    } 

		    // Get the answer (HTTP)
		    Response r = serve( uri, method, header, params );

		    // Return it
		    response.setContentType( r.getContentType() );
		    response.setStatus( HttpServletResponse.SC_OK );
		    response.getWriter().println( r.getData() );
		    ((Request)request).setHandled( true );
		}
	    };

	server.setHandler(handler);

	// Common part
	try { server.start(); }
	catch (Exception e) {
	    throw new Exception ( "Cannot launch HTTP Server" , e );
	}
	 		
    }   

    //Cette fonction récupère les données du navigateur, traite ces donnees,  frabrique une réponse en html et la retourne au navigateur
    public Response serve( String uri, String method, Properties header, Properties parms ) {
	 //comment recuperer les donees POST

System.out.println("PlanByCoServer : URI : "+uri+"\nPlanByCoServer : method : "+method);// header : "+header+"\n parms : "+parms);

	//Analyse des données reçues du navigateur
        Enumeration en = header.propertyNames();
	while ( en.hasMoreElements()) {
	    String value = (String)en.nextElement();
	}

	//Convertir parms en parameters.
	//Chaque pair (key, value) est séparé un ":" ??? dans URL 
	Properties params = new Properties();
	for ( String key : parms.stringPropertyNames() ) {
	     
	    if ( key.startsWith( "paramn" ) ){
		params.setProperty( parms.getProperty( key ),
				     parms.getProperty( "paramv"+key.substring( 6 ) ) );
	    } else if ( !key.startsWith( "paramv" ) ) {
		params.setProperty( key, parms.getProperty( key ) );
	    }
	}
	System.out.println("PlanByCoServer : params : "+params);
	
	//Analyse de l'URL
	int start = 0;
	while ( start < uri.length() && uri.charAt(start) == '/' ) start++;//on enleve les slash
	int end = uri.indexOf( '/', start+1 );//on cherche le slash de fin de la query en commencant a un char apres start. retourne -1 sinon
	String oper = "";
	if ( end != -1 ) {//oper correspond au chemin du fichier html depuis le premier slash (hors-mis le http://) jusqu'au dernier
	    oper = uri.substring( start, end );
	    start = end+1;
	    txt="oper : "+oper+"start : "+start;
	} else {
	    oper = uri.substring( start );
	    start = uri.length();
	    txt="oper1 : "+oper+" start1 : "+start;
	}

	//Some variables
	Response reponse = null;
	donnees = (donnees==null)?"PlanByCoServer : pas de query":donnees;
	String pageHeader = FileHandler.lire(CHEMINHTML+"enTete.html"); 
	String pageFooter = FileHandler.lire(CHEMINHTML+"piedPage.html"); 
	String pageEdt = null;
	String pageForm = FileHandler.lire(CHEMINHTML +"contrainte.html"); 

	int numPage=0;
	numPage=(uri.equals("/contrainte.html"))?1:numPage;
	numPage=(uri.equals("/next.html")==true)?2:numPage;
//System.out.println("numPage : " + numPage);

	
//En fonction de l'url, on change la reponse
	switch (numPage) {
		case 1 :
			System.out.println("PlanByCoServer : Ajout contrainte");

		//Action
			if (!donnees.equals("")){
				String[] partiesVariables = donnees.split("&");
				for (int j=0;j<partiesVariables.length;j++)
					System.out.println("PlanByCoServer : partiesVariables["+j+"]" +partiesVariables[j]);
			
				emploiDuTemps.ajouterContrainteSurProf(partiesVariables);
			}else {

				System.out.println("PlanByCoServer : No query");
			}
			pageEdt = FileHandler.lire(CHEMINHTML +EDTHTML); 
		//Affichage (controle)
			reponse = new Response( HTTP_OK, MIME_HTML, pageHeader+pageForm+pageEdt+pageFooter);
			break;

		case 2 :
			System.out.println("PlanByCoServer : Next");
			emploiDuTemps.next();
			pageEdt = FileHandler.lire(CHEMINHTML +EDTHTML); 
			reponse = new Response( HTTP_OK, MIME_HTML, pageHeader+pageForm+pageEdt+pageFooter);
			break;

		default : 
			System.out.println("PlanByCoServer : Default case");
			emploiDuTemps.solutionSansContraintes();
			pageEdt = FileHandler.lire(CHEMINHTML +EDTHTML); 
			reponse = new Response( HTTP_OK, MIME_HTML, pageHeader+pageForm+pageEdt+pageFooter);
			break;
	}
	System.out.println("PlanByCoServer : Fin d'envoi");
	return reponse;
	}


     public class Response {
	/**
	 * Default constructor: response = HTTP_OK, data = mime = 'null'
	 */
	public Response() {
	    this.status = HTTP_OK;
	}

	/**
	 * Basic constructor.
	 */
	public Response( String status, String mimeType, InputStream data ) {
	    this.status = status;
	    this.mimeType = mimeType;
	    this.data = data;
	}

	/**
	 * Convenience method that makes an InputStream out of
	 * given text.
	 */
	public Response( String status, String mimeType, String txt ) {
	    this.status = status;
	    this.mimeType = mimeType;
	    this.data = new ByteArrayInputStream( txt.getBytes());
	    // JE: Added
	    this.msg = txt;
	}

	 

	/**
	 * HTTP status code after processing, e.g. "200 OK", HTTP_OK
	 */
	public String status;

	/**
	 * MIME type of content, e.g. "text/html"
	 */
	public String mimeType;

	/**
	 * Data of the response, may be null.
	 */
	public InputStream data;

	/**
	 * Headers for the HTTP response. Use addHeader()
	 * to add lines.
	 */
	public Properties header = new Properties();
	// JE: Added for testing Jetty
	public String msg;
	public String getStatus() { return status; };
	public String getContentType() { return mimeType; }
	public String getData() { return msg; }

    }


}
